import { BadRequestException, Inject, Injectable } from '@nestjs/common';
import { ChangeBookingDto } from 'src/dto/ChangeBooking.dto';
import { EmailService } from 'src/email/email.service';
import { MeetingStatus } from 'src/enum';
import { PaginationService } from 'src/hooks/usePagination';
import { PrismaService } from 'src/prisma/prisma.service';
import { RedisService } from 'src/redis/redis.service';

@Injectable()
export class BookingService {
  @Inject(PrismaService)
  private readonly prisma: PrismaService;

  @Inject(RedisService)
  private readonly redis: RedisService;

  @Inject(EmailService)
  private readonly email: EmailService;

  @Inject(PaginationService)
  private readonly paginationService: PaginationService;

  async hasBookingExit(id: number) {
    const findBooking = await this.prisma.meeting.findUnique({
      where: {
        id,
      },
    });

    if (!findBooking) throw new BadRequestException('预定记录不存在');
  }

  async getBookingList(
    pageNum: number,
    pageSize: number,
    username: string,
    roomName: string,
    roomLocation: string,
    startTime: string,
    endTime: string,
  ) {
    const query = {
      where: {
        start_time: {
          gte: startTime && new Date(startTime),
          lte: endTime && new Date(endTime),
        },
        user: {
          username: {
            contains: username,
          },
        },
        room: {
          name: {
            contains: roomName,
          },
          location: {
            contains: roomLocation,
          },
        },
      },
    };

    const res = await this.paginationService.paginate(
      'meeting',
      query,
      pageNum,
      pageSize,
    );

    const ids = res.list.map((item) => item.id);
    const resWithUserAndRoom = await this.prisma.meeting.findMany({
      where: {
        id: {
          in: ids,
        },
      },
      include: {
        user: true,
        room: true,
      },
    });

    res.list = resWithUserAndRoom.map((item) => {
      Reflect.deleteProperty(item.user, 'password');
      return item;
    });
    return res;
  }

  async changeBookingStatus(changeBookingDto: ChangeBookingDto) {
    await this.hasBookingExit(changeBookingDto.id);

    await this.prisma.meeting.update({
      where: {
        id: changeBookingDto.id,
      },
      data: {
        status: changeBookingDto.status,
      },
    });
  }

  // 用户取消预定
  async cancelBooking(id: number) {
    await this.hasBookingExit(id);
    await this.prisma.meeting.update({
      where: {
        id,
      },
      data: {
        status: MeetingStatus.CANCELED,
      },
    });
  }

  // 用户催办
  async urge(id: number) {
    await this.hasBookingExit(id);
    const flag = await this.redis.get('urge_' + id);
    if (flag) return '半个小时内只能催办一次，请耐心等待';

    let admin_email = await this.redis.get('admin_email');

    if (!admin_email) {
      const admin = await this.prisma.user.findFirst({
        where: {
          is_admin: true,
        },
      });
      admin_email = admin.email;

      this.redis.set('admin_email', admin_email);
    }

    this.email.sendMail({
      to: admin_email,
      subject: '预定申请催办提醒',
      html: `您有新的预定申请正在等待审批， 点击链接直达：www.baidu.com`,
    });

    this.redis.set('urge_' + id, 1, 60 * 30);
  }
}
